#include "PrivateBusMaster.h"
uint8_t PrivateBus_Slave_Num;
const uint8_t PrivateBus_Slave_Num_Max=16;
//目标复制消息
uint8_t *callback_rx_buffer=NULL;
uint16_t *callback_rx_len=NULL;
uint8_t callback_rx_flag = 0;//BIT0 是否需要执行转换为主机消息



/**
  * @bried  私有协议主机初始化
  * @note   None
  * @param  None
  * @retval None
  */
PB_ERR PrivateBus_Master_Init(void){
    //自身占用偏移地址
    Addr_Offset[0][0]=0;//线圈
    Addr_Offset[0][1]=0;//离散输入
    Addr_Offset[0][2]=0;//输入寄存区
    Addr_Offset[0][3]=2;//保持寄存器（通讯波特率 传输延迟时间）

    uint8_t Sync_Rx[10];
    uint16_t Sync_Rx_Len;
    PrivateBus_Uart_Tx_Buffer[1]=0x41;//自定义命令字，查看配置信息命令字
    //寻找从机，从01遍历访问，超时结束
    for (uint8_t i = 1; i < PrivateBus_Slave_Num_Max; ++i) {
        PrivateBus_Uart_Tx_Buffer[0]=i;
        //PB_Get_CRC(_data,_len-2,&CRC_bit_L,&CRC_bit_H);
        PB_Get_CRC(PrivateBus_Uart_Tx_Buffer,2,&(PrivateBus_Uart_Tx_Buffer[2]),&(PrivateBus_Uart_Tx_Buffer[3]));
        if(PrivateBus_Master_Send_Sync(PrivateBus_Uart_Tx_Buffer,4,Sync_Rx,&Sync_Rx_Len,100)){
            //以接收到从机的配置信息
            Addr_Offset[i][0]=Sync_Rx[2]+Addr_Offset[i-1][0];
            Addr_Offset[i][1]=Sync_Rx[3]+Addr_Offset[i-1][1];
            Addr_Offset[i][2]=Sync_Rx[4]+Addr_Offset[i-1][2];
            Addr_Offset[i][3]=Sync_Rx[5]+Addr_Offset[i-1][3];
        } else{
            PrivateBus_Slave_Num=i - 1;//记录一共有多少个从机
            if(PrivateBus_Slave_Num){
                PB_Set_Bus_Led(PB_LED_STATE_ON);
            }else{
                PB_Set_Bus_Led(PB_LED_STATE_OFF);
            }
            break;
        }
    }
    PB_Set_Mcu_Led(PB_LED_STATE_ON);
    return PB_ERR_NONE;
}
/**
  * @bried  私有协议主机接收消息处理，处理返回的数据和主动上报的数据
  * @note   None
  * @param  None
  * @retval None
  */
void PrivateBus_Master_DealWith(uint8_t* _data,uint16_t _len){
    if (callback_rx_buffer!=NULL){
        memcpy(callback_rx_buffer,_data,_len);
        *callback_rx_len=_len;
        if (callback_rx_flag&0x01){
            PrivateBus_To_ModBus(callback_rx_buffer,*callback_rx_len);
            ModBus_busy_flag=0;//处理完成上一条消息
        }
    }
}
/**
  * @bried  主机发送消息，并接收返回的消息（异步）
  * @note   接收到的消息将填充到_callback_data，但是是异步的
  * @param  None
  * @retval None
  */
void PrivateBus_Master_Send_Async(uint8_t* _data,uint16_t _len,uint8_t* _callback_data,uint16_t* _callback_len){
    //设置返回接收缓冲区
    callback_rx_buffer=_callback_data;
    callback_rx_len=_callback_len;
    callback_rx_flag=0x01;//设置需要转换
    //开始发送
    PB_Send_Date(_data,_len);//发送消息
}
/**
  * @bried  主机发送消息，并接收返回的消息（同步阻塞）
  * @note   函数完成后返回是否成功
  * @param  None
  * @retval None
  */
bool PrivateBus_Master_Send_Sync(uint8_t* _data,uint16_t _len,uint8_t* _callback_data,uint16_t* _callback_len,uint16_t _timeout){
    PrivateBus_Master_Send_Async(_data,_len,_callback_data,_callback_len);
    callback_rx_flag = 0;//更改为不需要转换为ModBus主机
    //等待消息返回
    while (_timeout--){
        if (*callback_rx_len){//判断是否接受到数据
            callback_rx_buffer=NULL;
            callback_rx_len=NULL;
            return true;
        }
        PB_Delay(1);//等待1ms再判断是否返回消息
    }
    callback_rx_buffer=NULL;
    callback_rx_len=NULL;
    return false;
}
